﻿#include "SDL_Platform.h"
#include "SDL_Canvas.h"

#define CLO_SDL_INIT_FLAG		SDL_INIT_VIDEO | SDL_INIT_TIMER

SDL_CPlatform::SDL_CPlatform()
{
	m_pMainSurface = NULL;
}

SDL_CPlatform::~SDL_CPlatform()
{
}

bool SDL_CPlatform::InitPlatform(AF_CBundle* pParam)
{
	// 初始化SDL
	if(SDL_WasInit(CLO_SDL_INIT_FLAG) == 0)
	{
		if(SDL_Init(CLO_SDL_INIT_FLAG) == -1)
		{
			AF_ERROR("Init SDL Error!\n", "");
			return false;
		}
	}

	// 初始化TTF
	if(TTF_Init() == -1)
	{
		AF_ERROR("Init SDL_TTF Error!\n", "");
		return false;
	}

	return true;
}

bool SDL_CPlatform::DestroyPlatform()
{
	atexit(SDL_Quit);	// 程序崩溃时，也可以卸载SDL
	atexit(TTF_Quit);	// 程序崩溃时，也可以卸载SDL_TTF
	return true;
}

AF_DWindowHandle SDL_CPlatform::NewWindow(AF_SCreateWindow& cw)
{
	AF_CHECK_R(m_pMainSurface == NULL, NULL);

	SDL_Surface* _hSDLWindow = NULL;

	unsigned long _lVideoFlags = 0;
	
	// 显卡加速		
// 	_lVideoFlags |= SDL_HWSURFACE;
	// CPU加速
	_lVideoFlags |= SDL_SWSURFACE;

	// 全屏幕
	if(cw.isFullScreen)
	{
		_lVideoFlags |= SDL_FULLSCREEN;
		SDL_ShowCursor(0);
	}

	SDL_DPixelBit _pb = cw.bdlOther.GetInteger("PixelBit");
	if((_hSDLWindow = SDL_SetVideoMode(cw.nWidth, cw.nHeight, _pb, _lVideoFlags)) == NULL)
		return NULL;

	if(m_pMainSurface == NULL)
	{
		m_pMainSurface = _hSDLWindow;
	}

	return _hSDLWindow;
}

bool SDL_CPlatform::ShowWindow(AF_DWindowHandle hWindow)
{
	return true;
}

bool SDL_CPlatform::HideWindow(AF_DWindowHandle hWindow)
{
	return true;
}

void SDL_CPlatform::FlipWindow(AF_DWindowHandle hWindow)
{
	SDL_Flip((SDL_Surface*)hWindow);
}

bool SDL_CPlatform::DeleteWindow(AF_DWindowHandle hWindow)
{
	SDL_DWindowHandle _hSDLWindow = (SDL_DWindowHandle)hWindow;
	if(m_pMainSurface == _hSDLWindow)
	{
// 		SAFE_RELEASE(m_pMainSurface);
	}
	else
	{
// 		SAFE_RELEASE(_hSDLWindow);
	}

	return true;
}

void SDL_CPlatform::SetWindowTitle(AF_DWindowHandle hWindow, _STRING strTitle)
{
	AF_CHECK(strTitle != "");

	SDL_WM_SetCaption(strTitle.c_str(), NULL);
}

AF_CCanvas* SDL_CPlatform::CreateCanvas(AF_DWindowHandle pWndHandle)
{
	AF_CCanvas* pCanvas = AF_NEW(SDL_CCanvas);

	if(!pCanvas->Init(pWndHandle))
	{
		AF_DELETE(pCanvas);
	}

	return pCanvas;
}

bool SDL_CPlatform::DeleteCanvas(AF_CCanvas* pCanvas)
{
// 	AF_DELETE(pCanvas);
	return true;
}

bool SDL_CPlatform::GetEvent(AF_DWindowHandle pWndHandle, AF_SEvent& event)
{
	static SDL_Event SDLEvent;

	if(SDL_PollEvent(&SDLEvent) == 1)
	{
		switch(SDLEvent.type)
		{
		case SDL_KEYDOWN:
			event.nMessage = AF_EVENT_KEYBOARD_DOWN;
			event.lParam1 = event.lParam2 = (long)SDLEvent.key.keysym.sym;
			break;
		case SDL_KEYUP:
			event.nMessage = AF_EVENT_KEYBOARD_UP;
			event.lParam1 = event.lParam2 = (long)SDLEvent.key.keysym.sym;
			break;
		case SDL_MOUSEBUTTONDOWN:
			switch(SDLEvent.button.button)
			{
			case SDL_BUTTON_LEFT:
				event.nMessage = AF_EVENT_MOUSE_LEFT_DOWN;
				break;
			case SDL_BUTTON_RIGHT:
				event.nMessage = AF_EVENT_MOUSE_RIGHT_DOWN;
				break;
			default:
				event.nMessage = AF_EVENT_NOTHING;
				return false;
			}
			event.lParam1 = (long)SDLEvent.button.x;
			event.lParam2 = (long)SDLEvent.button.y;
			break;
		case SDL_MOUSEBUTTONUP:
			switch(SDLEvent.button.button)
			{
			case SDL_BUTTON_LEFT:
				event.nMessage = AF_EVENT_MOUSE_LEFT_UP;
				break;
			case SDL_BUTTON_RIGHT:
				event.nMessage = AF_EVENT_MOUSE_RIGHT_UP;
				break;
			default:
				event.nMessage = AF_EVENT_NOTHING;
				return false;
			}
			event.lParam1 = (long)SDLEvent.button.x;
			event.lParam2 = (long)SDLEvent.button.y;
			break;
		default:
			return false;
		}
		return true;
	}
	return false;
}

void SDL_CPlatform::CleanEventBuffer(AF_DWindowHandle pWndHandle)
{
	SDL_Event SDLEvent;
	while(SDL_PollEvent(&SDLEvent) == 1)
	{}
}

AF_DTimeTicks SDL_CPlatform::GetTimeTicks()
{
	return SDL_GetTicks();
}

void SDL_CPlatform::Delay(AF_DTimeTicks ttSleep)
{
	return SDL_Delay(ttSleep);
}

AF_DImageHandle SDL_CPlatform::CreateImage(
		const _STRING strPathName,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		AF_SImageInfo& _OUT ii
	)
{
	SDL_Surface* pLoad = NULL;
	pLoad = IMG_Load(strPathName.c_str());

	if(pLoad != NULL)
	{
		pLoad = SurfaceFormat(pLoad);

		nWidth = pLoad->w;
		nHeight = pLoad->h;
//		pb = pLoad->format->BitsPerPixel;
	}

	return pLoad;
}
AF_DImageHandle SDL_CPlatform::CreateImage(
		const void* pData,
		const SIZET nSize,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		AF_SImageInfo& _OUT ii
	)
{
	SDL_RWops* pRW = SDL_RWFromMem((void*)pData, nSize);

	SDL_Surface* pLoad = NULL;
	pLoad = IMG_Load_RW(pRW, 0);

	if(pLoad != NULL)
	{
		pLoad = SurfaceFormat(pLoad);

		nWidth = pLoad->w;
		nHeight = pLoad->h;
//		pb = pLoad->format->BitsPerPixel;
	}

	return pLoad;
}

AF_DImageHandle SDL_CPlatform::CreateImage(
		const UINT nWidth,
		const UINT nHeight,
		AF_SImageInfo& _OUT ii
	)
{
	SDL_Surface* pCreate = NULL;

	pCreate = SDL_CreateRGBSurface(SDL_HWSURFACE, nWidth, nHeight, SDL_PIXELBIT_32,
		m_pMainSurface->format->Rmask, m_pMainSurface->format->Gmask,
		m_pMainSurface->format->Bmask, m_pMainSurface->format->Amask);

	if(pCreate != NULL)
	{
		pCreate = SurfaceFormat(pCreate);
	}

	return pCreate;
}

bool SDL_CPlatform::GetImageInfo(
		AF_DImageHandle hImage,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		AF_SImageInfo& _OUT ii
	)
{
	AF_CHECK_R(hImage != NULL, false);

	SDL_Surface* pImage = (SDL_Surface*)hImage;
	nWidth = pImage->w;
	nHeight = pImage->h;
//	pb = pImage->format->BitsPerPixel;
	return true;
}

bool SDL_CPlatform::DeleteImage(AF_DImageHandle poiCur)
{
	AF_CHECK_R(poiCur != NULL, false);
	SDL_FreeSurface((SDL_Surface*)poiCur);
	return true;
}

// AF_CAudio* SDLPlatform::CreateAudio(AF_CBundle* pBundle)
// {
// 	CSDLAudio* pAudio = AF_NEW(CSDLAudio);
// 
// 	if(!pAudio->Init(pBundle))
// 	{
// 		CLO_ERROR_INIT_CLASS(CLO_CSDLAudio);
// 		AF_DELETE(pAudio);
// 		return NULL;
// 	}
// 	
// 	return pAudio;
// }
// 
// bool SDLPlatform::PlayAudio(const _STRING strPathName, bool isLoop)
// {
// 	return false;
// }



SDL_Surface* SDL_CPlatform::SurfaceFormat(SDL_Surface* pSrc)
{
	SDL_Surface* pReturn = NULL;
	if(pSrc != NULL)
	{
		pReturn = pSrc;
// 		pReturn = SDL_DisplayFormatAlpha(pSrc);
// 		SDL_FreeSurface(pSrc);
	}
	return pReturn;
}
